"初始化Vim设置
function! GeneralSettings()
	syntax on
	set hls
	set nowrap
	set incsearch
	set autoindent
	set smartindent
	set number
	"set relativenumber
	set noexpandtab			"是否用空格替换tab
	set tabstop=4			"一个tab四个空格宽
	set cindent
	set nobackup
	set softtabstop=4
	set shiftwidth=4		"自动缩进的单位空格数目,或者<<,>>手动缩进时移动的空格数目
	set scrolloff=5			"屏幕不移动时距离上下方的最短距离
	set ruler				"右下角显示标识
	set showcmd				"右下方显示输入的命令
	set encoding=utf-8
	set list listchars=eol:¬,tab:›\ ,trail:.
	set wildmenu
	set guioptions-=m
	set guioptions-=T
	set guioptions-=r
	set guioptions-=l
	set guioptions-=L
	set guioptions-=b
	set completeopt-=preview
	set backspace=2
	" set mouse=a
	"colorscheme desert
	colorscheme default
	filetype indent on
	nnoremap <silent> -d :g/\v^\s*$/d<enter>
	nnoremap <silent> -s :s/\v\s//g<enter>
	nnoremap <silent> -e :call Explanatory_note()<enter>
	nnoremap <silent> -r :call Run(1)<enter>
	nnoremap <silent> -c :call Run(0)<enter>
	nnoremap <silent> -- :call CloseDisplay()<enter>
	nnoremap <silent> <c-l> :nohlsearch<enter>
	nnoremap <c-y> mmgg"+yG`m
	nnoremap <c-p> "+P

	" 按左后退半页
	nnoremap <Left> <C-U>
	" 按右前进半页
	nnoremap <Right> <C-D>

	" 按Shift左后退一页
	nnoremap <S-Left> <C-B>
	" 按Shift右前进一页
	nnoremap <S-Right> <C-F>

	" 设置默认的正则模式
	nnoremap / /\v
	nnoremap ? ?\v

	" 回车时，如果当前有popupmenu，则会<ctrl-n>来选择下一个提示的补全内容：
	" 可参考：complete_info(), pumvisible()
	" 其中：pum 代表 popup menu，是出现的提示内容所在的菜单。
	silent inoremap <expr> <cr> pumvisible() ? "\<c-n>": "\<cr>"
	" 由于现代终端的问题，<shift-enter>无法被vim识别。所以下面这个map是无效的：
	silent inoremap <expr> <c-cr> pumvisible() ? "\<c-p>": "\<cr>"

	command Kill call JobStop()
	command Shuffle call Shuffle()
	command -range SortLines <line1>,<line2> call SortLines()
	command -range SetComment <line1>,<line2> call SetComment()
	" 多行Visual模式下, 注释当前行
	vnoremap <silent><space> :SetComment<enter>
	" 单行Normal模式下, 注释当前行
	nnoremap <silent><space> :SetComment<enter>
endfunction

"初始化全局变量
function! InitVariables()
	let g:tools = {"c":"gcc, gdb",
				\"cpp":"g++, gdb",
				\"java":"javac, java", 
				\"py":"python", 
				\"vhd":"Quartus ||",
				\"h":"gcc/g++, gdb",
				\ "asm":"nasm, ld",
				\ "rs": "rustc"}
	let g:name = "Wenhao"
	let g:email = "wh.wenhao@foxmail.com"
	let g:lineNum = 1
	let g:std_last_line_num = 1


	" snipMate插件的配置，为了不让出现警告信息。
	let g:snipMate = { 'snippet_version' : 1 }
endfunction

"针对不同文件，定义一些快捷键等。
function! SpecificSettings()
	if expand("%:e") == "py"
		set syntax=python
		inoremap :: <esc>A:<esc>o
	elseif expand("%:e") == "c"
		set syntax=c
		inoremap {{ <esc>o{}<esc>i<enter><esc>O
		inoremap {<enter> <esc>A{}<esc>i<enter><esc>O
		inoremap ;; <esc>A;<esc>o
	elseif expand("%:e") == "cpp"
		set syntax=c
		inoremap {{ <esc>o{}<esc>i<enter><esc>O
		inoremap {<enter> <esc>A{}<esc>i<enter><esc>O
		inoremap ;; <esc>A;<esc>o
		inoremap :: <esc>A:<esc>o
	elseif expand("%:e") == "h"
		set syntax=c
		inoremap {{ <esc>o{}<esc>i<enter><esc>O
		inoremap {<enter> <esc>A{}<esc>i<enter><esc>O
		inoremap ;; <esc>A;<esc>o
	elseif expand("%:e") == "java"
		set syntax=java
		inoremap {{ <esc>o{}<esc>i<enter><esc>O
		inoremap {<enter> <esc>A{}<esc>i<enter><esc>O
		inoremap ;; <esc>A;<esc>o
	elseif expand("%:e") == "vim"
	elseif expand("%:e") == "v"
		inoremap ;; <esc>A;<esc>o
	elseif expand("%:e") == "vhd"
		set syntax=vhdl
		inoremap ;; <esc>A;<esc>o
	elseif expand("%:e") == "asm"
		set syntax=masm
	elseif expand("%:e") == "js"
		inoremap {{ <esc>o{}<esc>i<enter><esc>O
		inoremap {<enter> <esc>A{}<esc>i<enter><esc>O
		inoremap ;; <esc>A;<esc>o
	elseif expand("%:e") == "rs"
		set syntax=rust
		inoremap {{ <esc>o{}<esc>i<enter><esc>O
		inoremap {<enter> <esc>A{}<esc>i<enter><esc>O
		inoremap ;; <esc>A;<esc>o
		set noexpandtab			"是否用空格替换tab
	elseif expand("%:e") == "command"
		set syntax=bash
	elseif expand("%:e") == "go"
		set syntax=go
		inoremap {<enter> <esc>A{}<esc>i<enter><esc>O
		inoremap ;; <esc>A;<esc>o
	endif
endfunction

"根据默认的行号往下一行一行写内容
function! MyAppend(str)
	call setline(g:lineNum, a:str)
	let g:lineNum = g:lineNum+1
endfunction

"根据不同的文件类型写入不同的文件头结构
function! InsertFileStructure()
	let g:lineNum = 1
	if expand("%:e") == "py"
		call MyAppend("#============================================================")
		call MyAppend("# Create Time:\t\t\t".strftime("%F %T"))
		call MyAppend("# Last modify:\t\t\t".strftime("%F %T"))
		call MyAppend("# Writer:\t\t\t\t".g:name."\t".g:email)
		call MyAppend("# File Name:\t\t\t".expand("%:t"))
		call MyAppend("# File Type:\t\t\t".toupper(expand("%:e"))." Source File")
		call MyAppend("# Tool:\t\t\t\t\t" .printf('%s -- vim & %s', has("unix")?"Mac":"Windows", g:tools[expand("%:e")]))
		call MyAppend("# Information:\t\t\t")
		call MyAppend("#============================================================")
		call MyAppend("")
	elseif expand("%:e") == "c"
		call MyAppend("/*============================================================")
		call MyAppend(" Create Time:\t\t\t".strftime("%F %T"))
		call MyAppend(" Last modify:\t\t\t".strftime("%F %T"))
		call MyAppend(" Writer:\t\t\t\t".g:name."\t".g:email)
		call MyAppend(" File Name:\t\t\t\t".expand("%:t"))
		call MyAppend(" File Type:\t\t\t\t".toupper(expand("%:e"))." Source File")
		call MyAppend(" Tool:\t\t\t\t\t" .printf('%s -- vim & %s', has("unix")?"Mac":"Windows", g:tools[expand("%:e")]))
		call MyAppend(" Information:\t\t\t")
		call MyAppend("============================================================*/")
		call MyAppend("#include <stdio.h>")
		call MyAppend("")
		call MyAppend("int main(int argc, char const *argv[])")
		call MyAppend("{")
		call MyAppend('	freopen("input.txt", "r", stdin);')
		call MyAppend("")
		call MyAppend("	return 0;")
		call MyAppend("}")
		call MyAppend("")
	elseif expand("%:e") == "cpp"
		call MyAppend("/*============================================================")
		call MyAppend(" Create Time:\t\t\t".strftime("%F %T"))
		call MyAppend(" Last modify:\t\t\t".strftime("%F %T"))
		call MyAppend(" Writer:\t\t\t\t".g:name."\t".g:email)
		call MyAppend(" File Name:\t\t\t\t".expand("%:t"))
		call MyAppend(" File Type:\t\t\t\t".toupper(expand("%:e"))." Source File")
		call MyAppend(" Tool:\t\t\t\t\t" .printf('%s -- vim & %s', has("unix")?"Mac":"Windows", g:tools[expand("%:e")]))
		call MyAppend(" Information:\t\t\t")
		call MyAppend("============================================================*/")
		call MyAppend("#include <cstdio>")
		call MyAppend("using namespace std;")
		call MyAppend("int main(int argc, char const *argv[])")
		call MyAppend("{")
		call MyAppend('	freopen("input.txt", "r", stdin);')
		call MyAppend("")
		call MyAppend("	return 0;")
		call MyAppend("}")
		call MyAppend("")
	elseif expand("%:e") == "h"
		call MyAppend("/*============================================================")
		call MyAppend(" Create Time:\t\t\t".strftime("%F %T"))
		call MyAppend(" Last modify:\t\t\t".strftime("%F %T"))
		call MyAppend(" Writer:\t\t\t\t".g:name."\t".g:email)
		call MyAppend(" File Name:\t\t\t\t".expand("%:t"))
		call MyAppend(" File Type:\t\t\t\t".toupper(expand("%:e"))." Source File")
		call MyAppend(" Tool:\t\t\t\t\t" .printf('%s -- vim & %s', has("unix")?"Mac":"Windows", g:tools[expand("%:e")]))
		call MyAppend(" Information:\t\t\t")
		call MyAppend("============================================================*/")
		call MyAppend("#ifndef ".tr(toupper(expand("%")), "\.", "_"))
		call MyAppend("#define ".tr(toupper(expand("%")), "\.", "_"))
		call MyAppend("")
		call MyAppend("#endif")
	elseif expand("%:e") == "java"
		call MyAppend("/*============================================================")
		call MyAppend(" Create Time:\t\t\t".strftime("%F %T"))
		call MyAppend(" Last modify:\t\t\t".strftime("%F %T"))
		call MyAppend(" Writer:\t\t\t\t".g:name."\t".g:email)
		call MyAppend(" File Name:\t\t\t\t".expand("%:t"))
		call MyAppend(" File Type:\t\t\t\t".toupper(expand("%:e"))." Source File")
		call MyAppend(" Tool:\t\t\t\t\t" .printf('%s -- vim & %s', has("unix")?"Mac":"Windows", g:tools[expand("%:e")]))
		call MyAppend(" Information:\t\t\t")
		call MyAppend("============================================================*/")
		call MyAppend("public class ".expand("%:r"))
		call MyAppend("{")
		call MyAppend("\tpublic static void main(String[] args)")
		call MyAppend("\t{")
		call MyAppend('		System.out.printf("Hello World\n");')
		call MyAppend("\t}")
		call MyAppend("}")
	elseif expand("%:e") == "vim"
		call MyAppend("\"============================================================")
		call MyAppend("\" Create Time:\t\t\t".strftime("%F %T"))
		call MyAppend("\" Last modify:\t\t\t".strftime("%F %T"))
		call MyAppend("\" Writer:\t\t\t\t".g:name."\t".g:email)
		call MyAppend("\" File Name:\t\t\t".expand("%:t"))
		call MyAppend("\" File Type:\t\t\t".toupper(expand("%:e"))." Source File")
		call MyAppend("\" GitHub:\t\t\t\t"."https://github.com/WenHao0804")
		call MyAppend("\" Information:\t\t\t")
		call MyAppend("\"============================================================")
	elseif expand("%:e") == "vhd"
		call MyAppend("#============================================================")
		call MyAppend("# Create Time:\t\t\t".strftime("%F %T"))
		call MyAppend("# Last modify:\t\t\t".strftime("%F %T"))
		call MyAppend("# Writer:\t\t\t\t".g:name."\t".g:email)
		call MyAppend("# File Name:\t\t\t".expand("%:t"))
		call MyAppend("# File Type:\t\t\t".toupper(expand("%:e"))." Source File")
		call MyAppend("# Tool:\t\t\t\t\t" .printf('%s -- vim & %s', has("unix")?"Mac":"Windows", g:tools[expand("%:e")]))
		call MyAppend("# Information:\t\t\t")
		call MyAppend("#============================================================")
		call MyAppend("library ieee;")
		call MyAppend("use ieee.std_logic_1164.all")
		call MyAppend("entity ".expand("%:r")." is")
		call MyAppend("\tport();")
		call MyAppend("end ".expand("%:r"))
		call MyAppend("")
		call MyAppend("architecture a of ".expand("%:r")." is")
		call MyAppend("\tbegin")
		call MyAppend("end a")
	elseif expand("%:e") == "asm"
		call MyAppend("data segment")
		call MyAppend("data ends")
		call MyAppend("")
		call MyAppend("stack segment stack")
		call MyAppend("stack ends")
		call MyAppend("")
		call MyAppend("code segment")
		call MyAppend("\tassume cs:code, ds:data, ss:stack")
		call MyAppend("start:")
		call MyAppend("\t")
		call MyAppend("\tmov ax, 4c00h")
		call MyAppend("\tint 21h")
		call MyAppend("code ends")
		call MyAppend("end start")
	elseif expand("%:e") == "rs"
		call MyAppend("/*============================================================")
		call MyAppend(" Create Time:\t\t\t".strftime("%F %T"))
		call MyAppend(" Last modify:\t\t\t".strftime("%F %T"))
		call MyAppend(" Writer:\t\t\t\t".g:name."\t".g:email)
		call MyAppend(" File Name:\t\t\t\t".expand("%:t"))
		call MyAppend(" File Type:\t\t\t\t".toupper(expand("%:e"))." Source File")
		call MyAppend(" Tool:\t\t\t\t\t" .printf('%s -- vim & %s', has("unix")?"Mac":"Windows", g:tools[expand("%:e")]))
		call MyAppend(" Information:\t\t\t")
		call MyAppend("============================================================*/")
		call MyAppend("fn main()")
		call MyAppend("{")
		call MyAppend("")
		call MyAppend("}")
		call MyAppend("")
	endif
endfunction

"更新最终修改时间
function! UpdateModifyTime()
	let line = getline(3)
	if(line =~ 'Last modify')
		let line = substitute(line, '\(\t\)\@<=\d\+.*$', strftime("%F %T"), "g")
		call setline(3, line)
	endif
endfunc

"自定义的一些功能函数
"从文档中选出不重复的所有单词
function! PickWord()
	try
		exec '%s/\W/\r/g' 
		exec 'g/\v^\s*$/d'
		exec 'g/\v^\d+$/d'
		"exec 'g/\v^.{1,3}$/d'
		
		"u means unique
		exec 'sort u' 
	endtry
endfunc

"2020-01-21
"给函数添加注释
function! Explanatory_note()
	let line = getline(".")
	let line = substitute(line, "^.*(", "", "g")
	let line = substitute(line, ").*$", "", "g")
	let args = split(line, ",")
	for i in range(len(args))
		let args[i] = substitute(args[i], ":.*", "", "g")
		let args[i] = trim(args[i])
		let args[i] = "@arg: ".args[i]." "
	endfor
	let args = ["@createTime: ".strftime("%F %T")] + args + ["@rtn: "]
	let explans = {"python":{"head":"\"\"\"", "tail":"\"\"\""},
				\"c":{"head":"/*", "tail":"*/"},
				\"h":{"head":"/*", "tail":"*/"},
				\"cpp":{"head":"/*", "tail":"*/"},
				\"java":{"head":"/*", "tail":"*/"},
				\}
	if has_key(explans, &ft)
		let args = [explans[&ft]['head']] + args + [explans[&ft]['tail']]
	else
		let tol = {"vim":"\"",} "top of line
		for i in range(len(args))
			let args[i] = tol[&ft].args[i]
		endfor
		unlet tol
	endif

	let line_num = line('.')
	if &ft == "java" || &ft == "c" || &ft == "cpp" || &ft == "h"
		let line_num = line_num + 1
	endif
	let args = reverse(args)
	for arg in args
		call append(line_num, arg)
	endfor
	exec "normal =".len(args)."j"
endfunction


func! Shuffle()
	"@createTime: 2022-03-05 10:05:56
	"@rtn: 随机按行打乱一个文件
	let num_lines = line('$')
	for i in range(num_lines)
		let line_idx = rand() % (num_lines - i) + 1
		exec printf("%dm$", line_idx)
	endfor
endfunc

function! PluginCheck()
	let $VIM_FILES = expand('$HOME/.vim')
	let $BUNDLE = expand('$VIM_FILES/autoload/plug.vim')
	let $PLUG_DIR = expand('$VIM_FILES/plugged')
	if(empty(glob($BUNDLE)))
		" silent !curl -fLo $BUNDLE --create-dirs
		" 			\ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
		 silent !curl -fLo $BUNDLE --create-dirs
		 			\ https://gitee.com/WenHao0804/my_vimrc/raw/master/plug.vim
	endif
	call plug#begin($PLUG_DIR)
		Plug 'fatih/vim-go', { 'do': ':GoUpdateBinaries' }
		Plug 'neoclide/coc.nvim', {'tag': 'v0.0.81'}
		"Plug 'valloric/youcompleteme'

		Plug 'MarcWeber/vim-addon-mw-utils'
		Plug 'tomtom/tlib_vim'
		Plug 'garbas/vim-snipmate'
		Plug 'honza/vim-snippets' "massive common snippets

		Plug 'Yggdroot/LeaderF', { 'do': './install.sh' }
		Plug 'github/copilot.vim'

		"Plug 'ZSaberLv0/ZFVimIM'
		"Plug 'ZSaberLv0/ZFVimJob' " optional, for better db load performance


		"Plug 'WenHao0804/my-vim-translator' "我自己的翻译插件
	call plug#end()
endfunction

function! SetComment() range
	"@createTime: 2023-02-21 14:35:37
	"对于范围内选中的行，为其添加注释或取消注释
	"添加注释的位置以选中的行的第一行为基准
	"如果一行内只有空格, 不为其添加注释
	let prefix_table = {
				\'py': '#',
				\'vim': '"',
				\'sh': '#',
				\'c': '//',
				\'cpp': '//',
				\'java': '//',
				\'h': '//',
				\}
	let prefix = get(prefix_table, expand("%:e"), "")
	if prefix == ""
		echo prefix
		return
	endif
	let space_len = len(matchlist(getline(a:firstline), '^\s*')[0])
	silent execute a:firstline . "," . a:lastline .
				\'s/\v(^\s{,'.space_len.'})(.*)/\=printf("%s%s",
				\submatch(1),
				\match(submatch(2), prefix) == 0?
					\substitute(submatch(2), printf("%s\\s", prefix), "", ""):
					\len(trim(submatch(2))) == 0?
						\submatch(2):
						\printf("%s %s", prefix, submatch(2))
				\)'
endfunction


function! SortLines() range
	"@createTime: 2022-10-10 16:07:09
	"@rtn: 按选定的范围将行排序, 排序依据为行内容长度
    silent execute a:firstline . "," . a:lastline . 's/^\(.*\)$/\=strdisplaywidth( submatch(0) ) . " " . submatch(0)/'
    silent execute a:firstline . "," . a:lastline . 'sort n'
    silent execute a:firstline . "," . a:lastline . 's/^\d\+\s//'
endfunction



"============= Run script and output in preview window ============= begin
"针对std_out的callback函数
"将std_out写入preview window的std_out部分。
func! RunJobOnStdout(type, content)
	wincmd P
	"call append(g:std_last_line_num, a:content)
	silent! let g:std_last_line_num = g:std_last_line_num + 1
	silent! call setline(g:std_last_line_num, a:content)
	silent! exec printf("%d wincmd _", min([s:output_buffer_max_height, g:std_last_line_num]))
	normal G
	noautocmd wincmd p
endfunc

"job结束时的callback函数
"修改preview window，删除不需要的变量
func! RunJobOnExit(type, msg)
	wincmd P

	" TODO:
	" 这里有个bug，当stdout的输出过快时(每条输出间隔大概 < 400 us)，不能正确输出所用时间。
	" 猜测是因为执行的func结束时，stdout还没有写完。
	"	 如果stdout先写完，则会在stdout的某行写入time
	"	 如果先写入time，则time会被stdout覆盖。
	" 暂时还没想到解决方法。
	" 
	"echo 'exit!!'
	"echo g:std_last_line_num

	let time_used_str =  printf('time used: %ss', reltimestr(reltime(s:start)))

	"silent! let g:std_last_line_num = g:std_last_line_num + 1
	"call append(g:std_last_line_num, 'STD_OUTPUT END.  '.time_used_str)
	call setline(line('$')+1, 'STD_OUTPUT END.  '.time_used_str)
	normal G
	"echo time_used_str
	exec printf("%d wincmd _", min([s:output_buffer_max_height, line('$')]))

	"unlet time_used_str
	noautocmd wincmd p
endfunc

"针对std_err的callback函数
"将std_err写入preview window中。
function! RunJobOnStderr(type, msg)
	":!ls
	wincmd P
	call append(line('$'), a:msg)
	noautocmd wincmd p
endfunction

"针对不同的文件类型，返回不同的执行命令。
func! GenerateBashRunCmd(run)
	if expand("%:e") == "py"
		if a:run == 0 "compile
			return ""
		else "execute
			return printf('python %s', expand("%:p"))
		endif
	elseif expand("%:e") == "js"
		return printf('node %s', expand("%:p"))
	elseif expand("%:e") == "cpp"
		"return printf('gcc %s && ./%s.out', expand("%:p"), expand("%:t:r"))
		if a:run == 0 "compile
			return printf('g++ -o %s.out %s', expand('%:t:r'), expand("%:t"))
		else "execute
			return printf('./%s.out', expand('%:t:r'))
		endif
	elseif expand("%:e") == "c"
		"return printf('gcc %s && ./%s.out', expand("%:p"), expand("%:t:r"))
		if a:run == 0 "compile
			return printf('gcc -o %s.out %s', expand('%:t:r'), expand("%:t"))
		else "execute
			return printf('./%s.out', expand('%:t:r'))
		endif
	elseif expand("%:e") == "rs"
		if a:run == 0 "compile
			return 'cargo build'
		else "execute
			return 'cargo run'
		endif
	elseif expand("%:e") == "go"
		if a:run == 0 "compile
			return 'go build'
		else "execute
			return printf('go run %s', expand("%:p"))
		endif
	endif
endfunc

"Close preview window.
func! CloseDisplay()
	pclose
endfunc

"If initial check is done, call this func to open
"a preview specifically tuned window.
func! OpenCleanPreviewWindow()
	try
		wincmd P
	catch
		noswapfile bo pedit
		wincmd P
		enew!
	endtry
	setlocal foldcolumn=0
	setlocal buftype=nofile
	setlocal bufhidden=wipe
	setlocal signcolumn=yes
	setlocal wrap nospell
	setlocal number norelativenumber
	setlocal noautoindent nosmartindent
	setlocal nobuflisted noswapfile nocursorline

	highlight notesGroup ctermfg=red guifg=red ctermbg=yellow guibg=yellow
	highlight errorGroup ctermfg=white guifg=white ctermbg=red guibg=red
	highlight stringGroup ctermfg=green guifg=green
	highlight integerGroup ctermfg=yellow guifg=yellow
	highlight urlGroup cterm=underline ctermfg=blue

	syntax match errorGroup 'Traceback.*$'
	syntax match notesGroup 'STD_OUTPUT.\{-\}[:\.]'
	syntax match stringGroup '\".\{-}[^\\]\"'
	syntax match stringGroup '\'.\{-}[^\\]\''
	syntax match integerGroup '\d\+'
	syntax match urlGroup '\w\+:\/\/\w\+\.\S\+'
	
	"clean the preview window
	let mem = @"
	normal ggdG
	let @" = mem
	unlet mem

	"resize preview window to minmum height
	1 wincmd _
	"init words in preview window
	call setline(1, 'STD_OUTPUT:')
	"go back to origin window
	wincmd p
endfunc

"Use this func to stop a inormal program
func! JobStop()
	if has_key(s:, 'run_job')
		call job_stop(s:run_job, 'kill')
	endif
endfunc

"Call this func to run the current editing script.
func! Run(run)
	let cmd = GenerateBashRunCmd(a:run)
	if cmd == ''
		return
	endif
	w "save file
	let g:std_last_line_num = 1
	call OpenCleanPreviewWindow()
	let Out_cb = function('RunJobOnStdout')
	let Err_cb = function('RunJobOnStderr')
	let Exit_cb = function('RunJobOnExit')

	let s:win_height = winheight(win_getid())
	let s:output_buffer_max_height = max([8, s:win_height / 5])
	
	let job_config = {
			\'out_cb': Out_cb,
			\'err_cb': Err_cb,
			\'exit_cb': Exit_cb,
			\'out_io': 'pipe',
			\'in_io': 'null',
			\'out_mode': 'nl',
			\'timeout': '3000'
			\}
	let s:start = reltime()
	if exists('*job_start')
		let s:run_job = job_start(cmd, job_config)
	elseif exists('*jobstart')
		let s:run_job = jobstart(cmd, job_config)
	endif
endfunc
"============= Run script and output in preview window ============= end

"主功能执行
if has('autocmd')
	call GeneralSettings()	"一般的设置
	call InitVariables()	"初始化全局变量
	call PluginCheck()		"检查插件管理器是否配置完毕

	"每一次进入一个buffer，就重新载入一次这个buffer对应的文件配置
	autocmd BufEnter * call SpecificSettings()

	"第一次且只有第一次创建某个文件时，添加文件头，和中间部分.
	autocmd BufNewFile * call InsertFileStructure()

	"每一次保存文件，自动更新最终更新时间
	autocmd BufWrite * call UpdateModifyTime()

	"将光标跳转至上次打开文件时的位置
	autocmd BufReadPost *
				\ if line("'\"") > 0 && line("'\"") <= line("$") |
				\   exe "normal g`\"" |
				\ endif

endif
